#include "protocol/modbus/ModbusTCP.h"
#include "core/Logger.h"
#include <iostream>
#include <thread>
#include <chrono>

int main(int argc, char* argv[]) {
    if (argc < 3) {
        std::cout << "Usage: " << argv[0] << " <host> <port>" << std::endl;
        std::cout << "Example: " << argv[0] << " 192.168.1.101 502" << std::endl;
        return 1;
    }

    std::string host = argv[1];
    int port = std::stoi(argv[2]);

    std::cout << "Scanning Modbus device: " << host << ":" << port << std::endl;
    std::cout << "========================================" << std::endl;

    // Test different slave IDs
    std::vector<int> slaveIds = {1, 2, 3, 247, 255};

    // Test common address ranges
    std::vector<int> addresses = {0, 1, 40001, 40100, 30001, 30100, 10001, 10100};

    for (int slaveId : slaveIds) {
        std::cout << "\nTesting Slave ID: " << slaveId << std::endl;
        std::cout << "--------------------" << std::endl;

        try {
            ems::protocol::ModbusTCP client(host, port);
            client.setSlaveId(slaveId);
            client.setTimeout(1000); // Shorter timeout for scanning

            if (!client.connect()) {
                std::cout << "❌ Connection failed for slave " << slaveId << std::endl;
                continue;
            }

            bool foundAny = false;

            for (int addr : addresses) {
                // Try holding registers
                std::vector<uint16_t> data;
                if (client.readHoldingRegisters(addr, 1, data)) {
                    std::cout << "✅ Holding Register " << addr << ": " << data[0] << std::endl;
                    foundAny = true;
                }

                // Try input registers
                if (client.readInputRegisters(addr, 1, data)) {
                    std::cout << "✅ Input Register " << addr << ": " << data[0] << std::endl;
                    foundAny = true;
                }

                // Try coils
                std::vector<bool> coils;
                if (client.readCoils(addr, 1, coils)) {
                    std::cout << "✅ Coil " << addr << ": " << (coils[0] ? "1" : "0") << std::endl;
                    foundAny = true;
                }

                // Try discrete inputs
                if (client.readDiscreteInputs(addr, 1, coils)) {
                    std::cout << "✅ Discrete Input " << addr << ": " << (coils[0] ? "1" : "0") << std::endl;
                    foundAny = true;
                }

                // Small delay between requests
                std::this_thread::sleep_for(std::chrono::milliseconds(50));
            }

            if (!foundAny) {
                std::cout << "❌ No responsive registers found for slave " << slaveId << std::endl;
            }

            client.disconnect();

        } catch (const std::exception& e) {
            std::cout << "❌ Exception for slave " << slaveId << ": " << e.what() << std::endl;
        }

        // Delay between slave tests
        std::this_thread::sleep_for(std::chrono::milliseconds(200));
    }

    std::cout << "\n========================================" << std::endl;
    std::cout << "Scan completed!" << std::endl;

    return 0;
}